2 Problem: 10167 - Birthday cake
3 (From the UVa Online Judge)
4 http://acm.uva.es/problemset/v101/10167.html
6 Divide-and-conquer solution
7 (Read problem "10077 - The Stern-Brocot number system" for an idea about the divide-and-conquer argument)
8 Basically I binary-search the perfect slope to cut the cake. It really isn't BINARY search, but every
9 time the space of slopes that can possibly be a solution is reduced considerably.
11 Author: Andrés Mejía-Posada
14 This code gets Accepted in the online judge.
28 point(const int &X
, const int &Y
) : x(X
), y(Y
) {}
34 line(const int &A
, const int &B
) : a(A
), b(B
) {}
37 line
operator |(const line
&a
, const line
&b
){
44 //Returns positive if p is to the left of line l
45 //Returns negative if p is to the right of line l
46 //Returns zero if p is colineal with line l
47 int cross(const point
&p
, const line
&l
){
52 return (p
.x
*q
.y
- q
.x
*p
.y
);
55 //Returns positive if line l should rotate left
56 //Returns negative if line l should rotate right
57 //Returns zero if line l is a solution
58 int check(const vector
<point
> &c
, const line
&l
){
59 int left
= 0, right
= 0;
60 for (int i
=0; i
<2*n
; ++i
){
61 int t
= cross(c
[i
], l
);
65 if (left
== right
&& left
< n
){ //2 or more points are colineal with the cut
66 return -1; //? Or return 1? Does it matter? (It also gets accepted with +1, 0 will give a wrong answer though).
68 return (left
- right
);
73 while (cin
>> n
&& n
){
74 vector
<point
> cherry(2*n
);
75 for (int i
=0; i
<2*n
; ++i
){
76 cin
>> cherry
[i
].x
>> cherry
[i
].y
;
79 line uphigh
, upmed
, updown
, downhigh
, downmed
, downdown
;
81 if (check(cherry
, uphigh
) == 0){
82 cout
<< uphigh
.a
<< " " << uphigh
.b
<< endl
;
86 if (check(cherry
, updown
) == 0){
87 cout
<< updown
.a
<< " " << updown
.b
<< endl
;
91 downhigh
= line(0, 1);
92 if (check(cherry
, downhigh
) == 0){
93 cout
<< downhigh
.a
<< " " << downhigh
.b
<< endl
;
97 downdown
= line(-1, 0);
98 if (check(cherry
, downdown
) == 0){
99 cout
<< downdown
.a
<< " " << downdown
.b
<< endl
;
106 upmed
= uphigh
| updown
;
107 int t
= check(cherry
, upmed
);
109 cout
<< upmed
.a
<< " " << upmed
.b
<< endl
;
117 downmed
= downhigh
| downdown
;
118 t
= check(cherry
, downmed
);
120 cout
<< downmed
.a
<< " " << downmed
.b
<< endl
;